﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;
using System.Diagnostics;

namespace Imaginecup.util.input
{
    public class GestureInputHandler : GameComponent
    {
        private static Game m_Game;
        private static GestureInputHandler m_InputHandler = null;

        private TouchCollection m_CurrentTouchCollection;   //현재 터치 패널상태
        private TouchCollection m_PrevTouchCollection;      //이전 터치 패널상태.

        private int m_nGesture = 0;
        private List<int> m_GestureList = new List<int>();
        private int m_Percent = 70;
        private Vector2 m_CurrentLocation;
        private Vector2 m_PrevLocation;

        private GestureInputHandler(Game game)
            : base(game)
        {
            m_PrevTouchCollection = TouchPanel.GetState();
            m_CurrentTouchCollection = TouchPanel.GetState();
        }

        public static void InitInput(Game game)
        {
            m_Game = game;
        }

        public static GestureInputHandler GetInputHandler()
        {
            if (m_InputHandler == null)
            {
                m_InputHandler = new GestureInputHandler(m_Game);
            }
            return m_InputHandler;
        }

        // 배열의 값 중 가장 큰 값의 인덱스를 리턴
        private int MaxNum(int[] numbers)
        {
            int count = 0;
            int tempNumber = numbers[0];
            for (int i = 1; i < numbers.Length; i++)
            {
                if (tempNumber < numbers[i])
                {
                    tempNumber = numbers[i];
                    count = i;
                }
            }
            return count;
        }
         
        private int GestureDistinction()
        {
            int[] direction = new int[5];
            int nGesture = 0;

            foreach (int number in m_GestureList)
            {
                direction[number]++;
            }

            int total = 0;
            foreach (int num in direction)
            {
                total += num;
            }

            int divide = direction[MaxNum(direction)];
            if (divide != 0)
            {
                if (total * 100 / divide >= m_Percent)
                {
                    Debug.WriteLine("Result : " + MaxNum(direction));
                    nGesture = MaxNum(direction);
                }
            }
            m_GestureList.Clear();
            return nGesture;
        }

        // 1. 오른쪽, 2. 위쪽, 3. 왼쪽, 4. 아래쪽
        int GestureDirectionRecognition( double angle )
        {
            int gestureNum = 0;
            //오른쪽
            if ((angle < 40.0f) && (angle > -40.0f))
            {
                gestureNum = 1;
            }
            //위쪽
            if ((angle > 50.0f) && (angle < 130.0f))
            {
                gestureNum = 2;
            }
            //왼쪽
            if  ( ((angle > 140.0f) && (angle < 180.0f)) || ((angle  > -180.0f) && (angle < -140.0f)) )
            {
                gestureNum = 3;
            }
            //아래쪽
            if ((angle > -130.0f) && (angle < -50.0f))
            {
                gestureNum = 4;
            }
            return gestureNum;
        }

        // 입력장치에 관한 업데이트
        public override void Update(GameTime gameTime)
        {
            m_PrevTouchCollection = m_CurrentTouchCollection;
            m_CurrentTouchCollection = PhoneInputHandler.GetInputHandler().GetCurrentTouch();

            if (m_CurrentTouchCollection.Count != 0)
            {
                if (m_CurrentTouchCollection[0].State == TouchLocationState.Pressed)
                {
                    m_CurrentLocation = Vector2.Zero;
                    m_PrevLocation = Vector2.Zero;
                    
                    m_PrevLocation = m_CurrentLocation;
                    m_CurrentLocation = m_CurrentTouchCollection[0].Position;
                }

                if(m_CurrentTouchCollection[0].State == TouchLocationState.Moved)
                {
                    m_PrevLocation = m_CurrentLocation;
                    m_CurrentLocation = m_CurrentTouchCollection[0].Position;

                    if(m_PrevLocation - m_CurrentLocation == Vector2.Zero)
                        return;
                    if ((m_CurrentLocation == Vector2.Zero) || (m_PrevLocation == Vector2.Zero))
                        return;

                    double dx = m_CurrentLocation.X - m_PrevLocation.X;
                    double dy = m_CurrentLocation.Y - m_PrevLocation.Y;

                    double angle = MathHelper.ToDegrees((float)Math.Atan2(-dy, dx));
                    Debug.WriteLine("--------------------------------------------------------------");
                    Debug.WriteLine(angle.ToString());
                    Debug.WriteLine(m_CurrentLocation.X.ToString() + " : " + m_PrevLocation.X.ToString());
                    Debug.WriteLine(m_CurrentLocation.Y.ToString() + " : " + m_PrevLocation.Y.ToString());
                    int nGesture;
                    if ((nGesture = GestureDirectionRecognition(angle)) != 0)
                        m_GestureList.Add(nGesture);
                    
                    Debug.WriteLine("Value : " + nGesture);    
                }

                if (m_CurrentTouchCollection[0].State == TouchLocationState.Released)
                {
                    m_nGesture = GestureDistinction();
                }
            }
        }

        public int Gesture
        {
            get { return m_nGesture; }
            set { m_nGesture = value; }
        }
        
        public TouchCollection GetCurrentTouch()
        {
            return m_CurrentTouchCollection;
        }

        public TouchCollection GetPrevTouch()
        {
            return m_PrevTouchCollection;
        }
    }
}
